// $codepro.audit.disable com.instantiations.assist.eclipse.analysis.audit.rule.effectivejava.alwaysOverridetoString.alwaysOverrideToString, com.instantiations.assist.eclipse.arrayIsStoredWithoutCopying, nullPointerDereference, reusableImmutables, spellCheckIdentifiers, spellCheckStringLiterals, unnecessaryImport, com.instantiations.assist.eclipse.callNextWithoutHasNext
/**
 * Package domain
 */
package teamrocket.domain; // $codepro.audit.disable packagePrefixNamingConvention -->

import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.logging.Level;

import teamrocket.db.DBWrapper;
import teamrocket.logging.TLogger;

/**
 * Represents a set of doctors orders in the system
 * @author Stephen
 * @version 1.0
 */
public class DoctorsOrders implements IDBObject<DoctorsOrders>{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	/**
	 * Field prescriptions
	 */
	private Prescription[] prescriptions;
	
	/**
	 * Field procedures
	 */
	private Procedure[] procedures;
	
	/**
	 * Field instructions
	 */
	private String instructions;
	
	/**
	 * Field follow-up instructions
	 */
	private String followUpInstructions;
	
	/**
	 * Field doctors orders ID
	 */
	private int orderid;
	
	/**
	 * This is the constructor for DoctorsOrders
	 * @param prescriptions
	 * @param procedures
	 * @param instructions
	 * @param followUpInstructions
	 */
	public DoctorsOrders(Prescription[] prescriptions, Procedure[] procedures,
			String instructions, String followUpInstructions) {
		this.prescriptions = prescriptions;
		this.procedures = procedures;
		this.instructions = instructions;
		this.followUpInstructions = followUpInstructions;
		TLogger.getInstance().getLogger().log(Level.INFO, "Creating new Doctors Orders");
	}
	
	/**
	 * This is the default constructor for DoctorsOrders
	 * @param proced
	 */
	public DoctorsOrders(Procedure proced){
		this.prescriptions = new Prescription[1];
		this.procedures = new Procedure[1];
		this.procedures[0] = proced;
		this.instructions = "";
		this.followUpInstructions = "";
		TLogger.getInstance().getLogger().log(Level.INFO, "Creating new Doctors Orders");
	}
	
	/**
	 * Method getPrescriptions.
	 * @return Prescription[]
	 */
	public Prescription[] getPrescriptions() {
		return prescriptions;
	}
	
	/**
	 * Method setPrescriptions.
	 * @param prescriptions Prescription[]
	 */
	public void setPrescriptions(Prescription[] prescriptions) {
		this.prescriptions = prescriptions;
	}
	
	/**
	 * Method getProcedures.
	 * @return Procedure[]
	 */
	public Procedure[] getProcedures() {
		return procedures;
	}
	
	/**
	 * Method setProcedures.
	 * @param procedures Procedure[]
	 */
	public void setProcedures(Procedure[] procedures) {
		this.procedures = procedures;
	}
	
	/**
	 * Method getInstructions.
	 * @return String
	 */
	public String getInstructions() {
		return instructions;
	}
	
	/**
	 * Method setInstructions.
	 * @param instructions String
	 */
	public void setInstructions(String instructions) {
		this.instructions = instructions;
	}
	
	/**
	 * Method getFollowUpInstructions.
	 * @return String
	 */
	public String getFollowUpInstructions() {
		return followUpInstructions;
	}
	
	/**
	 * Method setFollowUpInstructions.
	 * @param followUpInstructions String
	 */
	public void setFollowUpInstructions(String followUpInstructions) {
		this.followUpInstructions = followUpInstructions;
	}
	
	/**
	 * Method getOrderID.
	 * @return int
	 */
	public int getOrderID(){
		return this.orderid;
	}
	
	/**
	 * Method setOrderID.
	 * @param orderid int
	 */
	public void setOrderID(int orderid){
		this.orderid = orderid;
	}
	
	/**
	 * Method create.
	 * @return IDBObject<DoctorsOrders>
	 * @see teamrocket.domain.IDBObject#create()
	 */
	@Override
	public IDBObject<DoctorsOrders> create() {
		try{
			try {
				DBWrapper.execute("INSERT INTO drsorders " +
						"(instructions, followupinstructions) VALUES(?,?)", 
						this.instructions,
						this.followUpInstructions);
			
				final ResultSet rs = DBWrapper.query("SELECT id FROM " +
						"drsorders WHERE instructions = ? AND followupinstructions = ?",
						this.instructions,
						this.followUpInstructions);
				
				boolean empty = true;
				while(rs.next()){
					this.orderid = rs.getInt("id");
					empty = false;
					break;
				}
				if(empty){
					throw new Exception("Couldn't retrieve order ID.");
				}
				
				for(Prescription script : prescriptions){
					DBWrapper.execute("INSERT INTO prescriptions " +
							"(orderid, drugname, instructions) " +
							"VALUES (?, ?, ?)",
							this.orderid,
							script.getDrugName(),
							script.getInstructions());
				}
				for(Procedure procedure : procedures){
						DBWrapper.execute("INSERT INTO procedures " +
								"(orderid, date, name, performer, cost, patientid)" +
								"VALUES(?, ?, ?, ?, ?, ?)", 
								this.orderid,
								procedure.getDateOfProcedure().getTime(),
								procedure.getProcedureName(),
								procedure.getPerformedBy(),
								procedure.getCost(),
								procedure.getPatient());
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		TLogger.getInstance().getLogger().log(Level.INFO,
				"Creating Doctors Orders into database.");
		return this;
	}
	
	/**
	 * Method update.
	 * @see teamrocket.domain.IDBObject#update()
	 */
	@Override
	public void update() {
		try {
			DBWrapper.execute("UPDATE drsorders SET " +
					"instructions = ?, followupinstructions = ? WHERE id = ?",
					this.instructions,
					this.followUpInstructions,
					this.orderid);
			
			DBWrapper.execute("DELETE FROM prescriptions WHERE orderid = ?", 
					this.orderid);
			DBWrapper.execute("DELETE FROM procedures WHERE orderid = ?",
					this.orderid);
			
			for(Prescription script : prescriptions){
				DBWrapper.execute("INSERT INTO prescriptions " +
						"(orderid, drugname, instructions) " +
						"VALUES (?, ?, ?)",
						this.orderid,
						script.getDrugName(),
						script.getInstructions());
			}
			for(Procedure procedure : procedures){
					DBWrapper.execute("INSERT INTO procedures " +
							"(orderid, date, name, performer, cost, patientid)" +
							"VALUES(?, ?, ?, ?, ?, ?)", 
							this.orderid,
							procedure.getDateOfProcedure().getTime(),
							procedure.getProcedureName(),
							procedure.getPerformedBy(),
							procedure.getCost(),
							procedure.getPatient());
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		TLogger.getInstance().getLogger().log(Level.INFO,
				"Updating Doctors Orders in database.");
	}
	
	/**
	 * Method destroy.
	 * @see teamrocket.domain.IDBObject#destroy()
	 */
	@Override
	public void destroy() {
		try {
			DBWrapper.execute("DELETE FROM drsorders WHERE id = ?", 
					this.orderid);
			DBWrapper.execute("DELETE FROM prescriptions WHERE orderid = ?", 
					this.orderid);
			DBWrapper.execute("DELETE FROM procedures WHERE orderid = ?",
					this.orderid);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		TLogger.getInstance().getLogger().log(Level.INFO,
				"Deleting Doctors Orders in database.");
	}

	/**
	 * Gets all of the doctor's orders from the database
	
	 * @return Collection of DoctorsOrders */
	public static Collection<DoctorsOrders> getDrsOrders(){
		final Collection<DoctorsOrders> drsorders = new ArrayList<DoctorsOrders>();
		try {
			final ResultSet rs = DBWrapper.query("SELECT * FROM drsorders");
			while(rs.next()){
				Collection<Prescription> scripts = new ArrayList<Prescription>();
				Collection<Procedure> procedures = new ArrayList<Procedure>();
				
				ResultSet dbscripts = DBWrapper.query("SELECT * FROM " +
						"prescriptions WHERE orderid=?", rs.getInt("id"));
				
				while(dbscripts.next()){
					Prescription tempScript = new Prescription(
							dbscripts.getString("drugname"),
							dbscripts.getString("instructions"));
					scripts.add(tempScript);
				}
				
				Prescription[] scriptArray = new Prescription[0];
				Procedure[] procedureArray = new Procedure[0];
				DoctorsOrders toAdd = new DoctorsOrders(
						scripts.toArray(scriptArray),
						procedures.toArray(procedureArray),
						rs.getString("instructions"),
						rs.getString("followupinstructions"));
				toAdd.setOrderID(rs.getInt("id"));
				drsorders.add(toAdd);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		TLogger.getInstance().getLogger().log(Level.INFO,
				"Getting all Doctors Orders in database.");
		return drsorders;
	}
	
	/**
	 * Gets all of the doctor's orders from the database
	 * @param orderid int
	 * @return Collection of DoctorsOrders */
	public static Collection<DoctorsOrders> getDrsOrders(int orderid){
		final Collection<DoctorsOrders> drsorders = new ArrayList<DoctorsOrders>();
		try {
			final ResultSet rs = DBWrapper.query("SELECT * " +
					"FROM drsorders WHERE id=?", orderid);
			while(rs.next()){
				Collection<Prescription> scripts = new ArrayList<Prescription>();
				Collection<Procedure> procedures = new ArrayList<Procedure>();
				
				ResultSet dbscripts = DBWrapper.query("SELECT * FROM " +
						"prescriptions WHERE orderid=?", rs.getInt("id"));
				
				while(dbscripts.next()){
					Prescription tempScript = new Prescription(
							dbscripts.getString("drugname"),
							dbscripts.getString("instructions"));
					scripts.add(tempScript);
				}
				ResultSet proceduresScripts = DBWrapper.query("SELECT * FROM " +
						"procedures WHERE orderid=?", rs.getInt("id"));
				
				while(proceduresScripts.next()){
					Procedure tempScript2;
					tempScript2 = new Procedure(
							proceduresScripts.getDate("date"),
							proceduresScripts.getString("name"),
							proceduresScripts.getInt("performer"),
							proceduresScripts.getFloat("cost"),
							proceduresScripts.getInt("patientid"));
					procedures.add(tempScript2);
					
				}
				Prescription[] scriptArray = new Prescription[0];
				Procedure[] procedureArray = new Procedure[0];
				DoctorsOrders toAdd = new DoctorsOrders(
						scripts.toArray(scriptArray),
						procedures.toArray(procedureArray),
						rs.getString("instructions"),
						rs.getString("followupinstructions"));
				toAdd.setOrderID(rs.getInt("id"));
				drsorders.add(toAdd);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		TLogger.getInstance().getLogger().log(Level.INFO,
				"Getting all Doctors Orders in database.");
		return drsorders;
	}
}
